<?php
namespace Services;
/**
 * File holds class for account data manipulation
 *
 * PHP version 5.3.5
 *
 * @category   CM
 * @package    Services
 * @subpackage -
 * @author     markus karileet <markuskarileet@hotmail.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 * @link       -
 */
class Account extends ORM {
	/**
	 * Method checks if account data in session id valid.
	 * @return \Entities\Account When check is successful, account info is 
	 * returned, false otherwise
	 * @throws \Exception
	 */
	public function checkToken() {
		//try to read user from DB using session parameters
		$template = new \Entities\Account();
		$template->setId((int)@$_SESSION['userid']);
		$loggedUser = $this->select($template);
		$valid = false;
		//if user was found, check if session data is tampered or not
		if ($loggedUser) {
			if (@$_SESSION['token'] == self::_generateToken(
                $loggedUser->getId(), 
                $loggedUser->getName(), 
                $loggedUser->getLastlogin()
            )) {
				//session data untampered, procees
				$valid = $loggedUser;
			} else {
				//session data is corrupt, unset session and return false
				$this->clearUserData();
			}
		}
		return $valid;
	}
	
	/**
	 * Method authentices user from username and password. When match from
	 * DB is found, user info session is set and account last login time is 
	 * updated
	 * @param array $post HTML POST array 
	 * @return \Entities\Account Account info on success, false otherwise
	 * @throws \Exception
	 */
	public function authenticate($post) {
		//Read user from DB using username and pass
		$template = new \Entities\Account();
		$template->setName($post['name']);
		$template->setPassword(sha1($post['password']));
		$authUser = $this->select($template);
		//when user is found, set sessoin data
		if ($authUser) {
			$loginTime = time();
			$_SESSION['userid'] = $authUser->getId();
			$_SESSION['token'] = self::_generateToken(
                $authUser->getId(), 
                $authUser->getName(), 
                $loginTime
            );
			//update login time
			$authUser->setLastlogin($loginTime);
			$this->update($authUser);
		} 
		//return false or authenticated user
		return $authUser;
	}
	
	/**
	 * Method generates checksum token from user login info
	 * @param int $id User ID
	 * @param var $name User name
	 * @param int $time Last login time
	 * @return SHA1 hash from attributes
	 */
	private static function _generateToken($id, $name, $time) {
	    return sha1(sprintf('%d1%s2%s', $id, $name, $time));
	}
	
	/**
	 * Method unsets user session
	 */
	public function clearUserData() {
		unset($_SESSION['token']);
		unset($_SESSION['userid']);
	}
	
	/**
	 * Method updates user account. When newpassword element is set, system
	 * changes user password
	 * @param array $post HTTP POST
	 * @param \Entities\Account $user Account to update
	 * @return boolean true on success, false on error
	 * @throws \Exception
	 */
	public function prepareUpdate($post, $user) {
		if (isset($post['notify'])) {
			$user->setNotification(\Enum\Notification::Email);
		} else {
			$user->setNotification(\Enum\Notification::No);
		}
		$user->setEmail(\Misc\Tools::cleanInput($post['email']));
		if (isset($post['type'])) {
			$user->setType((int)$post['type']);
		}
		$user->setPhone(\Misc\Tools::cleanInput($post['phone']));
		//if new password is set, use it
		if (strlen($post['newpassword']) > 0) {
			$user->setPassword(sha1($post['newpassword']));
		}
		return $this->update($user);
	}
	
	/**
	 * Method inserts new account to database.
	 * @param var $post HTTP POST
	 * @return int Insert ID when successful
	 * @throws \Exception
	 */
	public function prepareInsert($post) {
		if(isset($post) && count($post) > 0 && $post['password'] == $post['r_password'] ) {
			$account = new \Entities\Account();
			$account->setContract("0"); //TODO: set contract in the future
			$account->setEmail(\Misc\Tools::cleanInput($post['email']));
			$account->setLastlogin("0");
			$account->setName(\Misc\Tools::cleanInput($post['name']));
			if (isset($post['notify'])) {
				$account->setNotification(1);
			} else {
				$account->setNotification("0");
			}
			$account->setPassword(sha1($post['password']));
			$account->setGivenname(\Misc\Tools::cleanInput($post['givenname']));
			$account->setPhone(\Misc\Tools::cleanInput($post['phone']));
			$account->setType("0");
			return $this->insert($account);
		}
	}
}